using System;
using System.IO;
using System.Runtime.CompilerServices;
using Godot;
using Godot.Collections;

public partial class BoomBody3d : RigidBody3D
{
	int contactCount = 0;
	private static PackedScene explosionScene;

	private Timer time;

	// Called when the node enters the scene tree for the first time.
	public override void _Ready()
	{
		time = new Timer()
		{
			WaitTime = 2f,
			OneShot = true
		};
		AddChild(time);
		time.Timeout += Explod;
		time.Start();
		var mi = new MeshInstance3D();
		mi.Mesh = GD.Load<ArrayMesh>("res://world/gernade.obj");
		mi.Scale = new Vector3(0.1f, 0.1f, 0.1f);
		mi.Position = new Vector3(0, -0.2f, 0);
		var shape = new CollisionShape3D();
		var sphere = new SphereShape3D();
		sphere.Radius = 0.5f;
		shape.Shape = sphere;
		AddChild(shape);
		AddChild(mi);
		BodyEntered += OnBodyEntered;
		ContactMonitor = true;
		MaxContactsReported = 1;
		var physicsMat = new PhysicsMaterial();
		physicsMat.Bounce = 1f;
		PhysicsMaterialOverride = physicsMat;
		if (explosionScene == null)
		{
			explosionScene = GD.Load<PackedScene>("res://world/Explosion.tscn");
		}
	}


	public override void _IntegrateForces(PhysicsDirectBodyState3D state)
	{
		if (state.GetContactCount() > 0)
		{
			var v = LinearVelocity;
			v = v.Normalized();
			Vector3 a = state.GetContactColliderPosition(0) - v / 2;
			Vector3I b = (Vector3I)a.Floor();
			VoxelWorld.voxelworld.SetBlockGlobalPosition((Vector3I)b, 0);		
		}
	}

	private void Explod()
	{
		Node3D node = explosionScene.Instantiate<Node3D>();
		node.Position = Position;
		GetParent().AddChild(node);
		QueueFree();
	}

	private void OnBodyEntered(Node body)
	{
		contactCount++;
		if (contactCount > -1)
		{
			if (body is Player)
			{
				Player player = (Player)body;
				Vector3 v = (player.Position - Position).Normalized();
				player.Velocity += 20 * v;
			}
			Explod();
		}
	}

	public static void Throw(SceneTree scene, Transform3D transform)
	{
		var gernade = new BoomBody3d();
		Vector3 velocity = transform * new Vector3(0, 0, -20f) - transform.Origin;
		Vector3 pos = transform * new Vector3(0, 0f, -2f);
		gernade.Position = pos;
		gernade.LinearVelocity = velocity;
		var rd = new Random();
		gernade.AngularVelocity = new Vector3(10.0f*(float)rd.NextDouble(),10*(float)rd.NextDouble(),10*(float)rd.NextDouble());
		scene.CurrentScene.AddChild(gernade);
	}
}
